package com.example.joke.base.http

import android.content.Context
import android.util.Log
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

class HttpUtils {

    // 直接带参数，链式调用（但不是builder设计模式）
    private lateinit var mUrl: String
    // 请求方式
    private val GET_TYPE = 0x0011
    private val POST_TYPE = 0x0022
    private var mType: Int = GET_TYPE

    private lateinit var mContext: Context
    private lateinit var mParams: HashMap<String, Any>

    val DEFAULT_CALL_BACK: EngineCallBack = object : EngineCallBack {
        override fun onPreExecute(context: Context, params: HashMap<String, Any>) {}
        override fun onError(e: Exception) {}
        override fun onSuccess(result: String) {}
    }

    // 默认OkhttpEngine
//    var mHttpEngine: IHttpEngine = OkhttpEngine()

    companion object {

        // 默认OkhttpEngine
        private var mHttpEngine: IHttpEngine = OkhttpEngine()

        fun with(context: Context) : HttpUtils {
            return HttpUtils(context)
        }

        // 在application初始化引擎
        fun init(httpEngine: IHttpEngine) {
            mHttpEngine = httpEngine
        }

        fun analysisClazzInfo(obj: Any) : Class<*> {
            val genType: Type = obj.javaClass.genericSuperclass
            val parameterizedType = genType as ParameterizedType
            val params: Array<out Type> = parameterizedType.actualTypeArguments
            return params[0] as Class<*>
        }
    }

    constructor(context: Context) {
        mContext = context
        mParams = HashMap()
    }

    
    fun url(url: String) : HttpUtils {
        mUrl = url
        return this
    }

    // 请求的方式
    fun post() : HttpUtils {
        mType = POST_TYPE
        return this
    }

    fun get() : HttpUtils {
        mType = GET_TYPE
        return this
    }

    // 添加参数
    fun addParam(key: String, value: Any) : HttpUtils {
        mParams.put(key, value)
        return this
    }

    fun addParams(params: Map<String, Any>) : HttpUtils {
        mParams.putAll(params)
        return this
    }

    // 添加回调，执行
    fun execute(callBack: EngineCallBack? = null) {

        val cb = callBack ?: DEFAULT_CALL_BACK

        // 每次执行都会进入这个方法:这里添加是行不通的
        // 1.base里面这里面不包含业务逻辑
        // 2.如果有多条业务线，
        // 让callBack回调去
        cb.onPreExecute(mContext, mParams)

        if (mType == POST_TYPE) {
            post(mUrl, mParams, cb)
        }
        if (mType == GET_TYPE) {
            get(mUrl, mParams, cb)
        }
    }

    fun execute() {
        Log.d("execute---", this.toString())
        execute(null)
    }


    // 每次可以自带引擎,使用与初始化时不一样的引擎
    fun exchangeEngine(httpEngine: IHttpEngine): HttpUtils {
        mHttpEngine = httpEngine
        return this
    }

    private fun get(url: String, params: Map<String, Any>, callback: EngineCallBack) {
        mHttpEngine.get(url, params, callback)
    }

    private fun post(url: String, params: Map<String, Any>, callback: EngineCallBack) {
        mHttpEngine.post(url, params, callback)
    }
}